/**
* @describe 跨平台请求基类
* @author 游金宇(KM)
* @date 2024-09-12 11:35:02
*/

import { getCommonSign } from "../hooks/api-sign/CommonSign";
import { error, log } from "cc";
import { Manager } from "@shimotsuki/core";

import { WECHAT } from "cc/env";

interface IResponse<T> {
    code: number;
    message: string;
    data: T;
    success: boolean;
}

type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';

interface RequestConfig {
    url: string;
    method?: RequestMethod;
    data?: any;
    headers?: Record<string, string>;
    timeout?: number;
}

export class BaseAPI {
    protected cat: Manager;
    protected baseURL: string;

    constructor(cat: Manager) {
        this.cat = cat;
        this.baseURL = cat.env.http_base_url;

        // 统一请求日志拦截
        this.requestInterceptor = this.requestInterceptor.bind(this);
        this.responseInterceptor = this.responseInterceptor.bind(this);
    }

    /** 请求拦截处理 */
    private requestInterceptor(config: RequestConfig) {
        const { method = 'GET', url, data } = config;

        // 彩色日志输出
        log(
            `%c HTTP请求地址 %c ${method} %c ${url}`,
            'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px;  color: #fff',
            'background:#41b883 ; padding: 1px; border-radius: 0 3px 3px 0;  color: #fff',
            'background:transparent'
        );

        // 签名处理
        const { sign, timestamp } = getCommonSign(data);

        return {
            ...config,
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${this.cat.store.login.access_token}`,
                'X-Signature': sign,
                'X-Timestamp': timestamp,
                ...config.headers
            }
        };
    }

    /** 响应拦截处理 */
    private responseInterceptor<T>(response: any): IResponse<T> {
        // 统一响应格式
        if (WECHAT) {
            return {
                code: response.statusCode,
                message: response.errMsg || '',
                data: response.data,
                success: response.statusCode === 200
            };
        }
        return response.data;
    }

    /** 核心请求方法 */
    protected async api<T>(config: RequestConfig): Promise<T> {
        const processedConfig = this.requestInterceptor(config);

        // 平台分支
        if (WECHAT) {
            return this.wechatRequest<T>(processedConfig);
        } else {
            return this.httpRequest<T>(processedConfig);
        }
    }

    /** 微信小程序请求实现 */
    private wechatRequest<T>(config: RequestConfig): Promise<T> {
        return new Promise((resolve, reject) => {
            wx.request({
                url: this.baseURL + '/' + config.url,
                method: config.method,
                data: config.data,
                header: config.headers,
                timeout: config.timeout || 5000,
                success: (res) => {
                    const response = (res.data as IResponse<T>)
                    if (res.statusCode !== 200) {
                        this.cat.gui.showToast({ title: res.errMsg });
                        reject(res.errMsg);
                        return;
                    }
                    if (response.code === 0) {
                        resolve(response.data);
                    } else {
                        this.cat.gui.showToast({ title: response.message });
                        reject(response);
                    }
                },
                fail: (err) => {
                    log('err', err);
                    this.cat.gui.showToast({ title: err.errMsg });
                    reject({
                        code: -1,
                        message: err.errMsg,
                        data: null,
                        success: false
                    });
                }
            });
        });
    }

    // 修改后的 httpRequest 方法（带类型修复）
    private async httpRequest<T>(config: RequestConfig): Promise<T> {
        return new Promise(async (resolve, reject) => {
            const axios = await import('@shimotsuki/axios');
            axios.default({
                ...config,
                url: this.baseURL + '/' + config.url,
                timeout: config.timeout || 5000
            }).then((response) => {
                const processed = this.responseInterceptor<T>(response);
                if (processed.code === 0) {
                    resolve(processed.data)
                } else {
                    this.cat.gui.showToast({ title: processed.message });
                    reject(processed.message)
                }
            }, err => {
                // 类型安全地处理错误
                const message = this.getErrorMessage(err);
                this.cat.gui.showToast({ title: message });
                reject(message)
            })
        })
    }

    // 👇 新增错误类型处理工具方法
    private getErrorMessage(error: unknown): string {
        // Axios 错误类型（需确保导入）
        if (this.isAxiosError(error)) {
            return error.message
                || '网络请求异常';
        }

        // 普通 Error 对象
        if (error instanceof Error) {
            return error.message;
        }

        // 其他未知类型
        return '未知错误';
    }

    // 👇 类型守卫函数（需导入 AxiosError 类型）
    private isAxiosError(error: unknown): error is import('@shimotsuki/axios').AxiosError {
        return (error as any).isAxiosError === true;
    }
}

